
#pragma once

#include "CoreMinimal.h"
#include "CollectableItem.h"
#include "PaperZDCharacter.h"
#include "PaperZDAnimInstance.h"

#include "InputAction.h"
#include "PlayerZDCharacter.generated.h"

/**
 * 
 */
UCLASS()
class PLATFORMJUMP_API APlayerZDCharacter : public APaperZDCharacter
{
	GENERATED_BODY()

private:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	class USpringArmComponent* SpringArmComponent;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	class UCameraComponent* CameraComponent;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	class UBoxComponent* AttackCollisionBox;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	class UInputMappingContext* InputMappingContext;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	UInputAction* MoveAction;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	UInputAction* JumpAction;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	UInputAction* AttackAction;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	UInputAction* ExitGameAction;
	
	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	UPaperZDAnimSequence* AttackAnimSequence;

	UPROPERTY(EditAnywhere, meta=(AllowPrivateAccess=true))
	TSubclassOf<class UPlayerHUD> PlayerHUDClass;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	UPlayerHUD* PlayerHUDWidget;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	class UPJGameInstance* MyGameInstance;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	USoundBase* ItemPickupSound;
	
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	int HitPoints = 100;
	
	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	int AttackDamage = 10;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess=true))
	float AttackStunDuration = 1.0f;
	
public:
	// 玩家是否处于存活状态
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	bool IsAlive = true;

	UPROPERTY(VisibleAnywhere)
	bool IsActive = true;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	bool IsStunned = false;
	
	// 玩家是否允许移动
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	bool CanMove = true;

	// 玩家是否可以攻击
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	bool CanAttack = true;

	FZDOnAnimationOverrideEndSignature OnAttackOverrideEndDelegate;

	FTimerHandle StunTimer;
	FTimerHandle RestartTimer;
	
public:
	APlayerZDCharacter();
	virtual void BeginPlay() override;
	virtual void Tick(float DeltaSeconds) override;
	virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;


	void Move(const FInputActionValue& Value);
	void JumpStarted(const FInputActionValue& Value);
	void JumpEnded(const FInputActionValue& Value);
	void Attack(const FInputActionValue& Value);
	void OnAttackOverrideAnimEnd(bool Completed);
	void UpdateDirection(float MoveDirection);

	UFUNCTION()
	void AttackBoxOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

	UFUNCTION(BlueprintCallable)
	void EnableAttackCollisionBox(bool Enabled);

	void TakeDamage(int DamageAmount, float StunDuration);
	void UpdateHP(int NewHP);

	void Stun(float DurationInSeconds);
	void OnStunTimerTimeout();

	void CollectItem(ECollectableType ItemType);
	void UnlockDoubleJump();

	void OnRestartTimerTimeout();

	void Deactivate();

	void QuitGame();
};
